import _ from 'lodash-es';
import angular from 'angular';
import { ResourceControlOwnership as RCO } from 'Portainer/models/resourceControl/resourceControlOwnership';
import { ResourceControlOwnershipParameters } from '../models/resourceControl/resourceControlOwnershipParameters';

class ResourceControlHelper {
  /**
   * Transform ResourceControlViewModel to ResourceControlOwnershipParameters
   * @param {int} userId ID of User performing the action
   * @param {ResourceControlViewModel} resourceControl ResourceControl view model
   */
  RCViewModelToOwnershipParameters(userId, resourceControl) {
    if (!resourceControl) {
      return new ResourceControlOwnershipParameters(true);
    }
    let adminOnly = false;
    let publicOnly = false;
    let users = [];
    let teams = [];
    switch (resourceControl.Ownership) {
      case RCO.PUBLIC:
        publicOnly = true;
        break;
      case RCO.PRIVATE:
        users = [userId];
        break;
      case RCO.RESTRICTED:
        users = _.map(resourceControl.UserAccesses, (user) => user.UserId);
        teams = _.map(resourceControl.TeamAccesses, (team) => team.TeamId);
        break;
      default:
        adminOnly = true;
        break;
    }
    return new ResourceControlOwnershipParameters(adminOnly, publicOnly, users, teams);
  }

  /**
   * Transform AccessControlFormData to ResourceControlOwnershipParameters
   * @param {int} userId ID of user performing the operation
   * @param {AccessControlFormData} formValues Form data (generated by AccessControlForm)
   * @param {int[]} subResources Sub Resources restricted by the ResourceControl
   */
  RCFormDataToOwnershipParameters(userId, formValues, subResources = []) {
    if (!formValues.AccessControlEnabled) {
      formValues.Ownership = RCO.PUBLIC;
    }

    let adminOnly = false;
    let publicOnly = false;
    let users = [];
    let teams = [];
    switch (formValues.Ownership) {
      case RCO.PUBLIC:
        publicOnly = true;
        break;
      case RCO.PRIVATE:
        users.push(userId);
        break;
      case RCO.RESTRICTED:
        users = _.map(formValues.AuthorizedUsers, (user) => user.Id);
        teams = _.map(formValues.AuthorizedTeams, (team) => team.Id);
        break;
      default:
        adminOnly = true;
        break;
    }
    return new ResourceControlOwnershipParameters(adminOnly, publicOnly, users, teams, subResources);
  }

  /**
   * Transform AccessControlPanelData to ResourceControlOwnershipParameters
   * @param {AccessControlPanelData} formValues Form data (generated by AccessControlPanel)
   */
  RCPanelDataToOwnershipParameters(formValues) {
    const adminOnly = formValues.Ownership === RCO.ADMINISTRATORS;
    const publicOnly = formValues.Ownership === RCO.PUBLIC;
    const userIds = publicOnly || adminOnly ? [] : _.map(formValues.Ownership_Users, (user) => user.Id);
    const teamIds = publicOnly || adminOnly ? [] : _.map(formValues.Ownership_Teams, (team) => team.Id);

    return new ResourceControlOwnershipParameters(adminOnly, publicOnly, userIds, teamIds);
  }

  retrieveAuthorizedUsers(resourceControl, users) {
    const authorizedUsers = [];
    _.forEach(resourceControl.UserAccesses, (access) => {
      const user = _.find(users, { Id: access.UserId });
      if (user) {
        authorizedUsers.push(user);
      }
    });
    return authorizedUsers;
  }

  retrieveAuthorizedTeams(resourceControl, teams) {
    const authorizedTeams = [];
    _.forEach(resourceControl.TeamAccesses, (access) => {
      const team = _.find(teams, { Id: access.TeamId });
      if (team) {
        authorizedTeams.push(team);
      }
    });
    return authorizedTeams;
  }

  isLeaderOfAnyRestrictedTeams(userMemberships, resourceControl) {
    let isTeamLeader = false;
    _.forEach(userMemberships, (membership) => {
      const found = _.find(resourceControl.TeamAccesses, { TeamId: membership.TeamId });
      if (found && membership.Role === 1) {
        isTeamLeader = true;
        return false;
      }
    });
    return isTeamLeader;
  }
}

export default ResourceControlHelper;
angular.module('portainer.app').service('ResourceControlHelper', ResourceControlHelper);
